package com.ccrfid.rmc6.service.sys;

import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.appconfig.exception.pojo.CustomErrors;
import com.ccrfid.rmc6.entity.sys.OrgEntity;
import com.ccrfid.rmc6.pojo.Constants;
import com.ccrfid.rmc6.repository.sys.OrgRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class OrgServiceImpl implements OrgService {
    private static final Logger logger = LoggerFactory.getLogger(OrgServiceImpl.class);
    @Autowired
    private OrgRepository orgRepository;

    @Override
    public List<OrgEntity> getOrgListByType(Integer typeId) {
        return orgRepository.getAllByOrgType(typeId);
    }

    @Override
    public List<OrgEntity> getOrgList() {
        return orgRepository.getAllBy();
    }

    @Override
    public List<OrgEntity> getSubOrgList(Long orgId) {
        OrgEntity entity = orgRepository.getById(orgId);
        if (entity != null) {
            return getSubOrgList(entity);
        }
        return null;
    }

    @Override
    public List<Long> getSubOrgIdList(Long orgId) {
        List<Long> idList = new ArrayList<>();
        idList.add(orgId);
        List<OrgEntity> subList = getSubOrgList(orgId);
        if (subList != null && !subList.isEmpty()) {
            for (OrgEntity entity : subList) {
                idList.add(entity.getId());
            }
        }
        return idList;
    }

    private List<OrgEntity> getSubOrgList(OrgEntity entity) {
        List<OrgEntity> resultList = new ArrayList<>();
        List<OrgEntity> subList = orgRepository.getAllByPid(entity.getId());
        if (subList != null && !subList.isEmpty()) {
            resultList.addAll(subList);
            for (OrgEntity subEntity : subList) {
                resultList.addAll(getSubOrgList(subEntity));
            }
        }
        return resultList;
    }

    @Override
    public OrgEntity getOrgInfoById(Long orgId) {
        return orgRepository.getById(orgId);
    }

    @Override
    public OrgEntity getOrgInfoBySn(String orgSn) {
        return orgRepository.getByOrgSn(orgSn);
    }

    @Override
    public OrgEntity createOrg(OrgEntity entity) throws AppException {
        if (entity.getOrgSn() != null && orgRepository.existsByOrgSn(entity.getOrgSn())) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.sn_conflict.getCode(), CustomErrors.sn_conflict.getReason(), "");
        }
        return orgRepository.save(entity);
    }

    @Override
    public OrgEntity updateOrg(Long orgId, OrgEntity entity) throws AppException {
        if (!orgId.equals(entity.getId())) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.different_args.getCode(), CustomErrors.different_args.getReason(), "");
        }
        if (!orgRepository.existsById(orgId)) {
            throw new AppException(Response.Status.NOT_FOUND.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        if (entity.getOrgSn() != null && orgRepository.existsByOrgSnAndIdNot(entity.getOrgSn(), orgId)) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.sn_conflict.getCode(), CustomErrors.sn_conflict.getReason(), "");
        }
        return orgRepository.save(entity);
    }

    @Override
    public int deleteOrgs(List<Long> idList) {
        int count = 0;
        for (Long id : idList) {
            if (orgRepository.existsById(id)) {
                OrgEntity entity = orgRepository.getById(id);
                deleteOrgAndSubOrgs(entity);
                count++;
            }
        }
        return count;
    }

    private void deleteOrgAndSubOrgs(OrgEntity entity) {
        if (orgRepository.existsByPid(entity.getId())) {
            //1.删除子部门
            List<OrgEntity> subList = orgRepository.getAllByPid(entity.getId());
            for (OrgEntity sub : subList) {
                deleteOrgAndSubOrgs(sub);
            }
            //2.删除自己
            orgRepository.deleteById(entity.getId());
        } else {
            //todo 此处添加关联信息的判断
            //
            orgRepository.deleteById(entity.getId());
        }
    }

    @Override
    public List<OrgEntity> getAllPrisonAreas() {
        return orgRepository.getAllByEnabledAndOrgTypeAndRemarkContainingOrderBySortNumber(1, Constants.ORG_TYPE.PRISONER.id, "监区");
    }

    @Override
    public List<OrgEntity> getAllPrisonAreasByOrgId(Long orgId) {
        List<Long> idList = getSubOrgIdList(orgId);
        if (idList != null) {
            return orgRepository.getAllByEnabledAndRemarkContainingAndIdInOrderBySortNumber(1, "监区", idList);
        } else {
            return new ArrayList<>(0);
        }
    }

    @Override
    public List<OrgEntity> getAllPrisonRooms() {
        return orgRepository.getAllByEnabledAndRemarkContainingOrderBySortNumber(1, "监室");
    }

    public List<OrgEntity> getAllPrisonRoomsByPid(Long orgId) {
        return orgRepository.getAllByPidAndEnabled(orgId, 1);
    }

    @Override
    public List<OrgEntity> getAllPrisonRoomsByOrgName(List<Long> orgIdList, String orgName){
        return orgRepository.getAllByIdInAndEnabledAndOrgNameContainingOrderBySortNumber(orgIdList,1,orgName);
    }
}
